home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / pinfocom_3_0.lha / Source / amiga_script.c < prev    next >
C/C++ Source or Header  |  1992-10-22  |  15KB  |  619 lines

  1. /* amiga_script.c
  2.  *
  3.  *  ``pinfocom'' -- a portable Infocom Inc. data file interpreter.
  4.  *  Copyright (C) 1987-1992  InfoTaskForce
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; see the file COPYING.  If not, write to the
  18.  *  Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /*
  22.  * $Header: RCS/amiga_script.c,v 3.0 1992/10/21 16:56:19 pds Stab $
  23.  */
  24.  
  25. #ifndef _AMIGA_GLOBAL_H
  26. #include "amiga_global.h"
  27. #endif    /* !_AMIGA_GLOBAL_H */
  28.  
  29.     /* ScriptWrite(const char *Buffer,int Width):
  30.      *
  31.      *    Write a null-terminated string to the
  32.      *    transcript file, adding a new-line
  33.      *    character.
  34.      */
  35.  
  36. Bool
  37. ScriptWrite(const char *Buffer,const int Width)
  38. {
  39.         /* Are we still to continue scripting? */
  40.  
  41.     if(ScriptAborted)
  42.         return(FALSE);
  43.     else
  44.     {
  45.         if(Width)
  46.         {
  47.                 /* Flush the current line buffer contents to the transcript
  48.                  * file, close it if the action fails.
  49.                  */
  50.  
  51.             if(!fwrite(Buffer,Width,1,ScriptFile))
  52.             {
  53.                 scr_putmesg("Error writing to transcript file",TRUE);
  54.  
  55.                 ScriptAborted = TRUE;
  56.  
  57.                 return(FALSE);
  58.             }
  59.         }
  60.  
  61.         if(!fwrite("\n",1,1,ScriptFile))
  62.         {
  63.             scr_putmesg("Error writing to transcript file",TRUE);
  64.  
  65.             ScriptAborted = TRUE;
  66.  
  67.             return(FALSE);
  68.         }
  69.  
  70.         return(TRUE);
  71.     }
  72. }
  73.  
  74.     /* ScriptCreateGadgets():
  75.      *
  76.      *    Create the gadgets for the printer control panel.
  77.      */
  78.  
  79. struct Gadget *
  80. ScriptCreateGadgets(struct Gadget **GadgetArray,struct Gadget **GadgetList,const APTR VisualInfo,UWORD *Width,UWORD *Height,const struct Screen *Screen)
  81. {
  82.         /* The gadget title labels. */
  83.  
  84.     STATIC STRPTR GadgetLabels[] =
  85.     {
  86.         "Transcript output file or device",
  87.         "Transcript page width",
  88.         "Okay",
  89.         "Cancel",
  90.         "Select a file..."
  91.     };
  92.  
  93.         /* A bunch of local variables. */
  94.  
  95.     struct Gadget        *Gadget;
  96.     struct NewGadget     NewGadget;
  97.     WORD             Counter = 0;
  98.  
  99.         /* Zero the template. */
  100.  
  101.     memset(&NewGadget,0,sizeof(struct NewGadget));
  102.  
  103.         /* Create the root info. */
  104.  
  105.     if(Gadget = CreateContext(GadgetList))
  106.     {
  107.         WORD    ButtonWidth,
  108.             StringWidth,
  109.             MaxWidth,
  110.             Temp,
  111.             i;
  112.  
  113.             /* Determine the longest string/integer gadget label. */
  114.  
  115.         MaxWidth = 0;
  116.  
  117.         for(i = SCRIPTGAD_PRINTER_STRING ; i <= SCRIPTGAD_PRINTER_WIDTH ; i++)
  118.         {
  119.             if((Temp = 2 * INTERWIDTH + TextLength((struct RastPort *)&Screen -> RastPort,GadgetLabels[i],strlen(GadgetLabels[i]))) > MaxWidth)
  120.                 MaxWidth = Temp;
  121.         }
  122.  
  123.             /* Store the longest label width. */
  124.  
  125.         StringWidth = MaxWidth;
  126.  
  127.             /* Determine the longest button gadget label. */
  128.  
  129.         MaxWidth = 0;
  130.  
  131.         for(i = SCRIPTGAD_PRINTER_ACCEPT ; i <= SCRIPTGAD_PRINTER_SELECT ; i++)
  132.         {
  133.             if((Temp = 2 * INTERWIDTH + TextLength((struct RastPort *)&Screen -> RastPort,GadgetLabels[i],strlen(GadgetLabels[i]))) > MaxWidth)
  134.                 MaxWidth = Temp;
  135.         }
  136.  
  137.             /* Store the longest label width. */
  138.  
  139.         ButtonWidth = MaxWidth;
  140.  
  141.             /* Are the three buttons in a row longer
  142.              * than the string/integer gadget? If so,
  143.              * adjust the string/integer gadget width.
  144.              */
  145.  
  146.         if(3 * ButtonWidth + 2 * INTERWIDTH > StringWidth)
  147.             StringWidth = 3 * ButtonWidth + 2 * INTERWIDTH;
  148.  
  149.             /* Determine window size. */
  150.  
  151.         *Width    = Screen -> WBorLeft + INTERWIDTH + StringWidth + INTERWIDTH + Screen -> WBorRight;
  152.         *Height    = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + 2 * (2 * INTERHEIGHT + Screen -> Font -> ta_YSize) + 3 * (Screen -> Font -> ta_YSize + 6) + 2 * INTERHEIGHT + Screen -> WBorBottom;
  153.  
  154.             /* Set up for gadget creation. */
  155.  
  156.         NewGadget . ng_GadgetText    = GadgetLabels[SCRIPTGAD_PRINTER_STRING];
  157.         NewGadget . ng_TextAttr        = Screen -> Font;
  158.         NewGadget . ng_VisualInfo    = VisualInfo;
  159.         NewGadget . ng_GadgetID        = Counter;
  160.         NewGadget . ng_Flags        = PLACETEXT_ABOVE;
  161.         NewGadget . ng_LeftEdge        = Screen -> WBorLeft + INTERWIDTH;
  162.         NewGadget . ng_TopEdge        = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + 2 * INTERHEIGHT + Screen -> Font -> ta_YSize;
  163.         NewGadget . ng_Width        = StringWidth;
  164.         NewGadget . ng_Height        = Screen -> Font -> ta_YSize + 6;
  165.  
  166.         GadgetArray[Counter++] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  167.             GTST_MaxChars,255,
  168.         TAG_DONE);
  169.  
  170.         NewGadget . ng_GadgetText    = GadgetLabels[SCRIPTGAD_PRINTER_WIDTH];
  171.         NewGadget . ng_GadgetID        = Counter;
  172.         NewGadget . ng_TopEdge        = NewGadget . ng_TopEdge + NewGadget . ng_Height + 2 * INTERHEIGHT + Screen -> Font -> ta_YSize;
  173.  
  174.         GadgetArray[Counter++] = Gadget = CreateGadget(INTEGER_KIND,Gadget,&NewGadget,TAG_DONE);
  175.  
  176.         NewGadget . ng_GadgetText    = GadgetLabels[SCRIPTGAD_PRINTER_ACCEPT];
  177.         NewGadget . ng_GadgetID        = Counter;
  178.         NewGadget . ng_Flags        = NULL;
  179.         NewGadget . ng_TopEdge        = NewGadget . ng_TopEdge + NewGadget . ng_Height + INTERHEIGHT;
  180.         NewGadget . ng_Width        = ButtonWidth;
  181.  
  182.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,TAG_DONE);
  183.  
  184.         NewGadget . ng_GadgetText    = GadgetLabels[SCRIPTGAD_PRINTER_CANCEL];
  185.         NewGadget . ng_GadgetID        = Counter;
  186.         NewGadget . ng_LeftEdge        = (*Width) - (Screen -> WBorLeft + INTERWIDTH + NewGadget . ng_Width);
  187.  
  188.         GadgetArray[Counter++] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,TAG_DONE);
  189.  
  190.         NewGadget . ng_GadgetText    = GadgetLabels[SCRIPTGAD_PRINTER_SELECT];
  191.         NewGadget . ng_GadgetID        = Counter;
  192.         NewGadget . ng_LeftEdge        = ((*Width) - NewGadget . ng_Width) / 2;
  193.  
  194.         GadgetArray[Counter] = Gadget = CreateGadget(BUTTON_KIND,Gadget,&NewGadget,TAG_DONE);
  195.     }
  196.  
  197.     return(Gadget);
  198. }
  199.  
  200.     /* ScriptGetPrinterName(STRPTR PrinterName,int *PrinterWidth):
  201.      *
  202.      *    Open the printer control panel.
  203.      */
  204.  
  205. Bool
  206. ScriptGetPrinterName(STRPTR PrinterName,int *PrinterWidth)
  207. {
  208.     STATIC char     FileName[MAX_FILENAME_LENGTH];
  209.  
  210.     struct Gadget    *GadgetArray[SCRIPTGAD_PRINTER_SELECT + 1],
  211.             *GadgetList;
  212.     struct Window    *PrinterWindow;
  213.     UWORD         Width,
  214.              Height;
  215.     char        *Index;
  216.     Bool         Result = FALSE;
  217.  
  218.         /* Get the path part of the file name,
  219.          * check if ends in a null-character,
  220.          * if so, it's probably just a device name.
  221.          */
  222.  
  223.     if(Index = PathPart(PrinterName))
  224.     {
  225.             /* If it has a file name attached, copy it to the filename buffer. */
  226.  
  227.         if(*Index)
  228.             strcpy(FileName,PrinterName);
  229.         else
  230.         {
  231.             int    ExtensionLen,
  232.                 NameLen,
  233.                 i;
  234.             Bool    GotIt = FALSE;
  235.  
  236.                 /* Use the story file name to start. */
  237.  
  238.             strcpy(FileName,gflags . filenm);
  239.  
  240.                 /* Determine name length. */
  241.  
  242.             NameLen = strlen(FileName);
  243.  
  244.                 /* Try to find a matching game
  245.                  * file name extension.
  246.                  */
  247.  
  248.             for(i = 0 ; !GotIt && StoryExtensions[i] ; i++)
  249.             {
  250.                     /* Is the game file name long enough
  251.                      * to hold an extension?
  252.                      */
  253.  
  254.                 if((ExtensionLen = strlen(StoryExtensions[i])) > NameLen)
  255.                 {
  256.                         /* Does the extension match? */
  257.  
  258.                     if(!Stricmp(&FileName[NameLen - ExtensionLen],StoryExtensions[i]))
  259.                     {
  260.                             /* Add new file name extension. */
  261.  
  262.                         strcpy(&FileName[NameLen - ExtensionLen],SCRIPT_EXT);
  263.  
  264.                             /* We're done now. */
  265.  
  266.                         GotIt = TRUE;
  267.                     }
  268.                 }
  269.             }
  270.  
  271.                 /* If we didn't succeed in adding
  272.                  * a new file name extension, just
  273.                  * attach the default.
  274.                  */
  275.  
  276.             if(!GotIt)
  277.             {
  278.                     /* Strip any existing extension. */
  279.  
  280.                 for(i = NameLen - 1 ; i >= 0 ; i--)
  281.                 {
  282.                     if(FileName[i] == '.')
  283.                     {
  284.                         FileName[i] = 0;
  285.  
  286.                         break;
  287.                     }
  288.                 }
  289.  
  290.                     /* Attach the default script
  291.                      * file name extension.
  292.                      */
  293.  
  294.                 strcat(FileName,SCRIPT_EXT);
  295.             }
  296.         }
  297.     }
  298.  
  299.         /* Create the gadgets for the window. */
  300.  
  301.     if(ScriptCreateGadgets(&GadgetArray[0],&GadgetList,VisualInfo,&Width,&Height,Window -> WScreen))
  302.     {
  303.             /* Open the window. */
  304.  
  305.         if(PrinterWindow = OpenWindowTags(NULL,
  306.             WA_Top,            Window -> TopEdge + (Window -> Height - Height) / 2,
  307.             WA_Left,        Window -> LeftEdge + (Window -> Width - Width) / 2,
  308.             WA_Title,        "Save transcript file",
  309.             WA_Width,        Width,
  310.             WA_Height,        Height,
  311.             WA_IDCMP,        IDCMP_VANILLAKEY | IDCMP_CLOSEWINDOW | STRINGIDCMP | BUTTONIDCMP,
  312.             WA_Activate,        TRUE,
  313.             WA_CloseGadget,        TRUE,
  314.             WA_DragBar,        TRUE,
  315.             WA_DepthGadget,        TRUE,
  316.             WA_RMBTrap,        TRUE,
  317.             WA_CustomScreen,    Window -> WScreen,
  318.         TAG_DONE))
  319.         {
  320.             STATIC struct Requester     BlockRequester;
  321.  
  322.             struct IntuiMessage    *Massage;
  323.             ULONG             Class;
  324.             struct Gadget        *Gadget;
  325.  
  326.             Bool             Terminated = FALSE;
  327.             STRPTR             Buffer;
  328.  
  329.                 /* Add the gadgets and render them. */
  330.  
  331.             AddGList(PrinterWindow,GadgetList,(UWORD)-1,(UWORD)-1,NULL);
  332.             RefreshGList(GadgetList,PrinterWindow,NULL,(UWORD)-1);
  333.             GT_RefreshWindow(PrinterWindow,NULL);
  334.  
  335.                 /* Set the string gadget (output file name). */
  336.  
  337.             GT_SetGadgetAttrs(GadgetArray[SCRIPTGAD_PRINTER_STRING],PrinterWindow,NULL,
  338.                 GTST_String,    PrinterName,
  339.             TAG_DONE);
  340.  
  341.                 /* Set the integer gadget (output file width). */
  342.  
  343.             GT_SetGadgetAttrs(GadgetArray[SCRIPTGAD_PRINTER_WIDTH],PrinterWindow,NULL,
  344.                 GTIN_Number,    *PrinterWidth,
  345.             TAG_DONE);
  346.  
  347.                 /* Activate the file/device name gadget. */
  348.  
  349.             ActivateGadget(GadgetArray[SCRIPTGAD_PRINTER_STRING],PrinterWindow,NULL);
  350.  
  351.                 /* A handy shortcut. */
  352.  
  353.             Buffer = GT_STRING(GadgetArray[SCRIPTGAD_PRINTER_STRING]);
  354.  
  355.                 /* Enter input loop. */
  356.  
  357.             do
  358.             {
  359.                     /* Wait for input. */
  360.  
  361.                 WaitPort(PrinterWindow -> UserPort);
  362.  
  363.                     /* Process all incoming messages. */
  364.  
  365.                 while(Massage = GT_GetIMsg(PrinterWindow -> UserPort))
  366.                 {
  367.                         /* Remember input class and gadget. */
  368.  
  369.                     Class    = Massage -> Class;
  370.                     Gadget    = (struct Gadget *)Massage -> IAddress;
  371.  
  372.                         /* Return the input event message. */
  373.  
  374.                     GT_ReplyIMsg(Massage);
  375.  
  376.                         /* Which kind of message did we receive? */
  377.  
  378.                     switch(Class)
  379.                     {
  380.                             /* Activate a string gadget? */
  381.  
  382.                         case IDCMP_VANILLAKEY:        ActivateGadget(GadgetArray[SCRIPTGAD_PRINTER_STRING],PrinterWindow,NULL);
  383.                                         break;
  384.  
  385.                             /* Close the window? */
  386.  
  387.                         case IDCMP_CLOSEWINDOW:        Terminated = TRUE;
  388.                                         break;
  389.  
  390.                             /* A button has been pressed? */
  391.  
  392.                         case IDCMP_GADGETUP:        switch(Gadget -> GadgetID)
  393.                                         {
  394.                                                 /* Activate the printer width gadget? */
  395.  
  396.                                             case SCRIPTGAD_PRINTER_STRING:ActivateGadget(GadgetArray[SCRIPTGAD_PRINTER_WIDTH],PrinterWindow,NULL);
  397.                                                         break;
  398.  
  399.                                                 /* Accept current settings. */
  400.  
  401.                                             case SCRIPTGAD_PRINTER_ACCEPT:if(Buffer[0])
  402.                                                         {
  403.                                                                 /* Copy the new printer output file/device name. */
  404.  
  405.                                                             strcpy(PrinterName,(char *)Buffer);
  406.  
  407.                                                                 /* Quit the loop the next time. */
  408.  
  409.                                                             Terminated = Result = TRUE;
  410.  
  411.                                                                 /* Get current printer width, don't make it too small. */
  412.  
  413.                                                             if((*PrinterWidth = GT_INTEGER(GadgetArray[SCRIPTGAD_PRINTER_WIDTH])) < MIN_PRINTER_COLUMNS)
  414.                                                                 *PrinterWidth = MIN_PRINTER_COLUMNS;
  415.                                                         }
  416.  
  417.                                                         break;
  418.  
  419.                                                 /* Select a new output file. */
  420.  
  421.                                             case SCRIPTGAD_PRINTER_SELECT:
  422.  
  423.                                                             /* Clear the requester. */
  424.  
  425.                                                         memset(&BlockRequester,0,sizeof(struct Requester));
  426.  
  427.                                                             /* Block window input. */
  428.  
  429.                                                         Request(&BlockRequester,PrinterWindow);
  430.  
  431.                                                             /* Set the window wait pointer. */
  432.  
  433.                                                         WaitPointer(PrinterWindow);
  434.  
  435.                                                         strcpy(TempBuffer,FileName);
  436.  
  437.                                                             /* Extract the path name. */
  438.  
  439.                                                         if(Index = PathPart(TempBuffer))
  440.                                                             *Index = 0;
  441.  
  442.                                                             /* If no path name is given, supply the
  443.                                                              * current directory.
  444.                                                              */
  445.  
  446.                                                         if(!TempBuffer[0])
  447.                                                         {
  448.                                                                 /* Try to obtain the current directory name.
  449.                                                                  * If this fails, leave the path name empty.
  450.                                                                  */
  451.  
  452.                                                             if(!GetCurrentDirName(TempBuffer,MAX_FILENAME_LENGTH))
  453.                                                                 TempBuffer[0] = 0;
  454.                                                         }
  455.  
  456.                                                             /* Request the file name. */
  457.  
  458.                                                         if(AslRequestTags(GameFileRequest,
  459.                                                             ASL_Window,    PrinterWindow,
  460.                                                             ASL_Dir,    TempBuffer,
  461.                                                             ASL_File,    FilePart(FileName),
  462.                                                             ASL_FuncFlags,    FILF_SAVE,
  463.                                                             ASL_Hail,    "Select transcript file to save",
  464.                                                             ASL_Pattern,    "~(#?.info)",
  465.                                                         TAG_DONE))
  466.                                                         {
  467.                                                                 /* Did we get a file name? */
  468.  
  469.                                                             if(GameFileRequest -> rf_File[0])
  470.                                                             {
  471.                                                                     /* Copy the drawer name. */
  472.  
  473.                                                                 strcpy(TempBuffer,(char *)GameFileRequest -> rf_Dir);
  474.  
  475.                                                                     /* Add the file name. */
  476.  
  477.                                                                 if(AddPart(TempBuffer,GameFileRequest -> rf_File,MAX_FILENAME_LENGTH))
  478.                                                                 {
  479.                                                                         /* Update the file name string. */
  480.  
  481.                                                                     GT_SetGadgetAttrs(GadgetArray[SCRIPTGAD_PRINTER_STRING],PrinterWindow,NULL,
  482.                                                                         GTST_String,TempBuffer,
  483.                                                                     TAG_DONE);
  484.  
  485.                                                                         /* Remember the file name. */
  486.  
  487.                                                                     strcpy(FileName,TempBuffer);
  488.                                                                 }
  489.                                                             }
  490.                                                         }
  491.  
  492.                                                         ClearPointer(PrinterWindow);
  493.  
  494.                                                         EndRequest(&BlockRequester,PrinterWindow);
  495.  
  496.                                                         break;
  497.  
  498.                                                 /* Cancel the requester. */
  499.  
  500.                                             case SCRIPTGAD_PRINTER_CANCEL:Terminated = TRUE;
  501.                                                         break;
  502.                                         }
  503.  
  504.                                         break;
  505.                     }
  506.  
  507.                     if(Terminated)
  508.                         break;
  509.                 }
  510.             }
  511.             while(!Terminated);
  512.  
  513.                 /* Close the printer control window. */
  514.  
  515.             CloseWindow(PrinterWindow);
  516.         }
  517.  
  518.             /* Free the gadgets. */
  519.  
  520.         FreeGadgets(GadgetList);
  521.     }
  522.  
  523.     return(Result);
  524. }
  525.  
  526.     /* ScriptSplitLine(char *Line,int Len,const Bool ReturnPrompt):
  527.      *
  528.      *    Split a hunk of text into neat little pieces.
  529.      */
  530.  
  531. char *
  532. ScriptSplitLine(char *Line,int Len,const Bool ReturnPrompt)
  533. {
  534.     int     Count,
  535.          Space;
  536.  
  537.         /* Process & chop the text. */
  538.  
  539.     do
  540.     {
  541.             /* Does the entire line fit? */
  542.  
  543.         if(Len <= ScriptWidth)
  544.         {
  545.             if(ReturnPrompt)
  546.                 return(Line);
  547.             else
  548.                 ScriptWrite(Line,Count = Len);
  549.         }
  550.         else
  551.         {
  552.                 /* Reset the counters. */
  553.  
  554.             Space = Count = 0;
  555.  
  556.                 /* Determine number of
  557.                  * characters to fit and
  558.                  * the last space to use
  559.                  * for text-wrapping.
  560.                  */
  561.  
  562.             while(Count < Len && Count + 1 < ScriptWidth)
  563.             {
  564.                 Count++;
  565.  
  566.                     /* Remember last space. */
  567.  
  568.                 if(Line[Count] == ' ')
  569.                     Space = Count;
  570.             }
  571.  
  572.                 /* Return remainder. */
  573.  
  574.             if(Count == Len)
  575.             {
  576.                 if(ReturnPrompt)
  577.                     return(Line);
  578.                 else
  579.                 {
  580.                     if(Line[Count - 1] == ' ')
  581.                         ScriptWrite(Line,Count - 1);
  582.                     else
  583.                         ScriptWrite(Line,Count);
  584.                 }
  585.             }
  586.             else
  587.             {
  588.                     /* Write the line. */
  589.  
  590.                 if(Line[Count - 1] == ' ')
  591.                 {
  592.                     if(!ScriptWrite(Line,Count - 1))
  593.                         break;
  594.                 }
  595.                 else
  596.                 {
  597.                     if(!ScriptWrite(Line,Space))
  598.                         break;
  599.                     else
  600.                         Count = Space + 1;
  601.                 }
  602.             }
  603.  
  604.                 /* Move up. */
  605.  
  606.             Line += Count;
  607.         }
  608.  
  609.             /* Reduce remaining length. */
  610.  
  611.         Len -= Count;
  612.     }
  613.     while(Len > 0);
  614.  
  615.         /* Return blank line. */
  616.  
  617.     return("");
  618. }
  619.